package utils;

import java.util.HashMap;
import java.util.Map;

import container.Weapon;
import container.WeaponTrait;
import container.WeaponTraitDescription;

/**
 * Utility class for weapons
 * 
 * @author Ioana
 * 
 */
public class WeaponUtil {
	private FormulaCalculator calculator = new FormulaCalculator();
	private Map<Integer, Double> accuracyTable = new HashMap<Integer, Double>();
	private Map<String, WeaponTraitDescription> availableWeaponTraits = new HashMap<String, WeaponTraitDescription>();

	public WeaponUtil() {
		this.accuracyTable.put(Integer.valueOf(-3), Double.valueOf(0.35));
		this.accuracyTable.put(Integer.valueOf(-2), Double.valueOf(0.5));
		this.accuracyTable.put(Integer.valueOf(-1), Double.valueOf(0.71));
		this.accuracyTable.put(Integer.valueOf(0), Double.valueOf(1.0));
		this.accuracyTable.put(Integer.valueOf(1), Double.valueOf(1.41));
		this.accuracyTable.put(Integer.valueOf(2), Double.valueOf(2.0));
		this.accuracyTable.put(Integer.valueOf(3), Double.valueOf(2.83));
	}

	/**
	 * Calculates the cost of the weapon.
	 * 
	 * @param weapon
	 *            the weapon for which the costs are calculated
	 * 
	 * @return the cost of the weapon
	 */
	public long calculateWeaponCost(Weapon weapon) {
		double cost = weapon.getDamageMultiplicator()
				* weapon.getOptimalRange()
				* this.accuracyTable.get(Double.valueOf(weapon.getAccuracy()))
						.doubleValue();

		for (WeaponTrait trait : weapon.getWeaponsTraits()) {
			cost *= getTraitMultiplier(trait);
		}

		return Math.round(cost);

	}

	/**
	 * Returns the multiplier for this trait.
	 * 
	 * @param trait
	 *            trait for which the multiplier is calculated
	 * 
	 * @return multiplier
	 */
	private double getTraitMultiplier(WeaponTrait trait) {
		WeaponTraitDescription traitDescription = this.availableWeaponTraits
				.get(trait.getTraitCode());
		String traitFormula = traitDescription.getRatingFormula();

		double result = this.calculator.calculateFormula(traitFormula, trait
				.getRating());

		return result;
	}
}
